<style>
div.ztree_content_wrap {
        /* height:380px;  */
	/* overflow: hidden; */
}
div.ztree_content_wrap:hover{
	/* overflow: inherit; */
	position: relative;
	z-index: 9999;
}
div.ztree_content_wrap div.left {
	float: left;
	/* width: 100%; */
}

div.zTreeDemoBackground {
	/* width: 100%; */
        /* height:500px; */
	text-align: left;
	
}

.expendIcon {
	background-position: -74px -36px;
	line-height: 0;
	margin: 0;
	width: 16px;
	height: 16px;
	display: inline-block;
	vertical-align: middle;
	border: 0 none;
	cursor: pointer;
	outline: none;
	position: absolute;
	top: 4px;
	background-color: transparent;
	background-repeat: no-repeat;
	background-attachment: scroll;
	background-image: url("../images/ztree/zTreeStandard.png");
}

ul.ztree {
	/* border: 1px solid #ddd; */
	background: #ffffff;
	width: 100%;
	height: auto;
/*overflow-y:scroll;*/
	overflow-x: auto;
}

.ztree * {
	padding: 0;
	margin: 0;
	font-size: 15px;
	font-family: Verdana, Arial, Helvetica, AppleGothic, sans-serif
}

.ztree {
	margin: 0;
	padding: 5px;
	color: #333;
}

.ztree li {
	position: relative;
	padding: 0;
	margin: 0;
	list-style: none;
	line-height: 24px;
	text-align: left;
	white-space: nowrap;
	outline: 0
}
.ztree li .t-b{
	position: absolute;
    border-top: 1px dashed #999;
    /* bottom: 50px; */
    height: 1px;
    top: 14px;
    left: -10px;
    width: 20px;
}
.ztree li ul {
	position: relative;
	margin: 0;
	padding: 0 0 0 18px;
}
.ztree li .l-b{
	position: absolute;
    border-left: 1px dashed #999;
    /* bottom: 50px; */
    height: 100%;
    top: -11px;
    left: -12px;
    width: 1px;
}
.ztree li .l-b-d{
	height: 24px;
}
.ztree li ul.line {
	background: url('../images/ztree/line_conn.gif') 0 0 repeat-y;
}

.ztree li a {
	padding: 1px 3px 0 5px;
	margin: 0;
	cursor: pointer;
	/* height: 17px; */
	color: #333;
	background-color: transparent;
	text-decoration: none;
	vertical-align: top;
	display: inline-block
}

.ztree li a:hover {
	text-decoration: underline;
	color: blue;
}

.ztree li a.curSelectedNode {
	border-radius: 3px;
	padding-top: 0px;
	background-color: #191d22;
	color: #fff;
	height: 26px;
	border: 1px #191d22 solid;
	opacity: 0.8;
}

.ztree li a.curSelectedNode_Edit {
	padding-top: 0px;
	background-color: #FFE6B0;
	color: black;
	height: 16px;
	border: 1px #FFB951 solid;
	opacity: 0.8;
}

.ztree li a.tmpTargetNode_inner {
	padding-top: 0px;
	background-color: #316AC5;
	color: white;
	height: 16px;
	border: 1px #316AC5 solid;
	opacity: 0.8;
	filter: alpha(opacity=80)
}

.ztree li a.tmpTargetNode_prev {
}

.ztree li a.tmpTargetNode_next {
}

.ztree li a input.rename {
	height: 14px;
	width: 80px;
	padding: 0;
	margin: 0;
	font-size: 12px;
	border: 1px #7EC4CC solid;
	*border: 0px
}

.ztree li span {
	line-height: 16px;
	margin-right: 2px;
	top: 3px;
	display: inline-block;
}

.ztree li span.button {
	line-height: 0;
	margin: 0;
	width: 12px;
	height: 12px;
	display: inline-block;
	/* vertical-align: middle; */
	border: 0 none;
	cursor: pointer;
	outline: none;
	/* background-color: transparent;
	background-repeat: no-repeat;
	background-attachment: scroll; */
	/* background-image: url("../images/ztree/zTreeStandard.png");
	*background-image: url("../images/ztree/zTreeStandard.gif") */
}

.ztree li span.button.chk {
	width: 13px;
	height: 13px;
	margin: 0 3px 0 0;
	cursor: auto
}

.ztree li span.button.chk.checkbox_false_full {
	background-position: 0 0
}

.ztree li span.button.chk.checkbox_false_full_focus {
	background-position: 0 -14px
}

.ztree li span.button.chk.checkbox_false_part {
	background-position: 0 -28px
}

.ztree li span.button.chk.checkbox_false_part_focus {
	background-position: 0 -42px
}

.ztree li span.button.chk.checkbox_false_disable {
	background-position: 0 -56px
}

.ztree li span.button.chk.checkbox_true_full {
	background-position: -14px 0
}

.ztree li span.button.chk.checkbox_true_full_focus {
	background-position: -14px -14px
}

.ztree li span.button.chk.checkbox_true_part {
	background-position: -14px -28px
}

.ztree li span.button.chk.checkbox_true_part_focus {
	background-position: -14px -42px
}

.ztree li span.button.chk.checkbox_true_disable {
	background-position: -14px -56px
}

.ztree li span.button.chk.radio_false_full {
	background-position: -28px 0
}

.ztree li span.button.chk.radio_false_full_focus {
	background-position: -28px -14px
}

.ztree li span.button.chk.radio_false_part {
	background-position: -28px -28px
}

.ztree li span.button.chk.radio_false_part_focus {
	background-position: -28px -42px
}

.ztree li span.button.chk.radio_false_disable {
	background-position: -28px -56px
}

.ztree li span.button.chk.radio_true_full {
	background-position: -42px 0
}

.ztree li span.button.chk.radio_true_full_focus {
	background-position: -42px -14px
}

.ztree li span.button.chk.radio_true_part {
	background-position: -42px -28px
}

.ztree li span.button.chk.radio_true_part_focus {
	background-position: -42px -42px
}

.ztree li span.button.chk.radio_true_disable {
	background-position: -42px -56px
}

.ztree li span.button.switch {
	width: 12px;
	height: 12px
}

.ztree li span.button.root_open {
	position: relative;
	border: 1px solid #000;
	background:rgb(255, 255, 255);
	z-index: 2;
	border-radius: 100%;
}

.ztree li span.button.root_close {
	position: relative;
	border: 1px solid #000;
	background:rgb(0, 0, 0);
	color: #fff;
	top:1px;
	z-index: 2;
	border-radius: 100%;
}

.ztree li span.button.root_open::before {
	content: '-';
	text-align: center;
    display: block;
    width: 10px;
    height: 10px;
    line-height: 10px;
}
.ztree li span.button.root_close::before {
	content: '+';
	text-align: center;
    display: block;
    width: 10px;
    height: 10px;
    line-height: 10px;
	font-size: 12px;
}

.ztree li span.button.roots_open {
	background-position: -92px 0
}

.ztree li span.button.roots_close {
	background-position: -74px 0
}

.ztree li span.button.center_open {
	position: relative;
	border: 1px solid #000;
	background:rgb(255, 255, 255);
	z-index: 2;
	border-radius: 100%;
}

.ztree li span.button.center_close {
	position: relative;
	border: 1px solid #000;
	background:rgb(0, 0, 0);
	color: #fff;
	top:1px;
	z-index: 2;
	border-radius: 100%;
}

.ztree li span.button.center_open::before {
	content: '-';
	text-align: center;
    display: block;
    width: 10px;
    height: 10px;
    line-height: 10px;
}
.ztree li span.button.center_close::before {
	content: '+';
	text-align: center;
    display: block;
    width: 10px;
    height: 10px;
    line-height: 10px;
	font-size: 12px;
}

.ztree li span.button.bottom_open {
	position: relative;
	border: 1px solid #000;
	background:rgb(255, 255, 255);
	z-index: 2;
	border-radius: 100%;
}

.ztree li span.button.bottom_close {
	position: relative;
	border: 1px solid #000;
	background:rgb(0, 0, 0);
	color: #fff;
	top:1px;
	z-index: 2;
	border-radius: 100%;
}

.ztree li span.button.bottom_open::before {
	content: '-';
	text-align: center;
    display: block;
    width: 10px;
    height: 10px;
    line-height: 10px;
}
.ztree li span.button.bottom_close::before {
	content: '+';
	text-align: center;
    display: block;
    width: 10px;
    height: 10px;
    line-height: 10px;
	font-size: 12px;
}

.ztree li span.button.noline_open {
	background-position: -92px -72px
}

.ztree li span.button.noline_close {
	background-position: -74px -72px
}

.ztree li span.button.root_docu {
	background: none;
}

.ztree li span.button.roots_docu {
	background-position: -56px 0
}

.ztree li span.button.center_docu {
	width: 6px;
    height: 6px;
    position: relative;
    top: 0px;
    left: 4px;
    border-radius: 100%;
    background: #999;
    z-index: 2;
}

.ztree li span.button.bottom_docu {
	width: 6px;
    height: 6px;
    position: relative;
    top: 0px;
    left: 4px;
    border-radius: 100%;
    background: #999;
    z-index: 2;
}

.ztree li span.button.noline_docu {
	background: none;
}

.ztree li span.button.ico_open {
	margin-right: 2px;
	background-position: -110px -16px;
	vertical-align: top;
	*vertical-align: middle
}

.ztree li span.button.ico_close {
	margin-right: 2px;
	background-position: -110px 0;
	vertical-align: top;
	*vertical-align: middle
}

.ztree li span.button.ico_docu {
	margin-right: 2px;
	background-position: -110px -32px;
	vertical-align: top;
	*vertical-align: middle
}

.ztree li span.button.edit {
	margin-right: 2px;
	background-position: -110px -48px;
	vertical-align: top;
	*vertical-align: middle
}

.ztree li span.button.remove {
	margin-right: 2px;
	background-position: -110px -64px;
	vertical-align: top;
	*vertical-align: middle
}
	/*.ztree li span.button.ico_loading{margin-right:2px; background:url('../images/ztree/loading.gif') no-repeat scroll 0 0 transparent; 
	            vertical-align:top; *vertical-align:middle}*/
ul.tmpTargetzTree {
	background-color: #FFE6B0;
	opacity: 0.8;
	filter: alpha(opacity=80)
}

span.tmpzTreeMove_arrow {
	width: 16px;
	height: 16px;
	display: inline-block;
	padding: 0;
	margin: 2px 0 0 1px;
	border: 0 none;
	position: absolute;
	background-color: white;
	background-repeat: no-repeat;
	background-attachment: scroll;
	background-position: -110px -80px;
	background-image: url("../images/ztree/zTreeStandard.png");
	*background-image: url("../images/ztree/zTreeStandard.gif")
}

ul.ztree.zTreeDragUL {
	margin: 0;
	padding: 0;
	position: absolute;
	width: auto;
	height: auto;
	overflow: hidden;
	background-color: #cfcfcf;
	border: 1px #00B83F dotted;
	opacity: 0.8;
	filter: alpha(opacity=80)
}

.zTreeMask {
	z-index: 10000;
	background-color: #cfcfcf;
	opacity: 0.0;
	filter: alpha(opacity=0);
	position: absolute
}

.loadSyncNode {
	width: 16px;
	height: 16px;
	position: relative;
	display: inline-block;
	background-image: url("")
}
.clearfloat{clear:both} 
</style>

<template>
	<!--（ztree－🌲）-->
	<div class="ztree_content_wrap" v-if='treeDataSource.length>0'>
		<div class="zTreeDemoBackground left">
			<ul class="ztree">
				<ztree-item v-for='(m,i) in treeDataSource' :key='i' :model.sync="m" :num.sync='i' root='0' :nodes.sync='treeDataSource.length' :callback='func' :expandfunc='expand' :cxtmenufunc='contextmenu' :trees.sync='treeDataSource'></ztree-item>
			</ul>
		</div>
		<div class="clearfloat"></div> 
	</div>
</template>

<script>
import Vue from 'vue'
export default{
	data(){
       return {
       	  treeDataSource:[]
       }
	},
	name:'ocTree',
	props:{
		// 树数据
        list:{
       	  	type:Array,
       	  	twoWay:true
        },
        // 点击节点回调
		func:{
			type:Function,
			default:null
		},
		// 点击展开回调
		expand:{
            type:Function,
            default:null
		},
		// 右击事件
		contextmenu:{
            type:Function,
            default:function(){
            	
            }
		},
		// 是否展开
		isOpen:{
			type:Boolean,
			twoWay:true,
			default:false
		}
	},
	watch:{
        'list': {
            handler:function(){
            	this.initTreeData();
            },
            deep:true
        }
	},
	methods:{
        initTreeData(){
            var tempList = JSON.parse(JSON.stringify(this.list));
            
            // 递归操作，增加删除一些属性。比如: 展开/收起
            var recurrenceFunc = (data) => {
                data.forEach((m)=>{
                    if(!m.hasOwnProperty("clickNode")){
	                    m.clickNode = m.hasOwnProperty("clickNode") ? m.clickNode : false;
	                }
                    m.Children = m.Children || [];
            
                    if(	!m.hasOwnProperty("isFolder") ) {
	               		m.isFolder =  m.hasOwnProperty("open") ? m.open : this.isOpen;
	                }
	                if(	!m.hasOwnProperty("isExpand") ) {
	               		m.isExpand =  m.hasOwnProperty("open") ? m.open : this.isOpen;
	               	}
	               	m.loadNode = 0; 
	               	
	               	recurrenceFunc(m.Children);
    
                    
                })
            };
            recurrenceFunc(tempList);
            this.treeDataSource = tempList;
        }
	},
	components:{
		// 组件
        ztreeItem:{
        	name: 'ztreeItem',
        	props: {
        		model:{
        			type:Object,
        			twoWay:true
        		},
        		num:{
                    type:Number,
                    twoWay:true
        		},
        		nodes:{
                    type:Number,
                    twoWay:true,
                    default:0
        		},
        		trees:{
		       	  	type:Array,
		       	  	twoWay:true,
		       	  	default:[]
		        },
        		root:{
                    type:String,
                    twoWay:true
        		},
        		callback:{
					type:Function
				},
				expandfunc:{
					type:Function
				},
				cxtmenufunc:{
					type:Function
				}
			},
			created(){
				if(this.root==0){
					this.Func(this.trees[0])
				}
			},
        	methods:{
                Func(m){
					// 
                    // 查找点击的子节点
                    var recurFunc = (data,list) => {
                        data.forEach((i)=>{
                            if(i.User.id==m.User.id){
                                i.clickNode = true;
                                if(typeof this.callback == "function") {
				                    this.callback.call(null,m,list,this.trees);
				                }
                            }else {
                              i.clickNode = false;
                            }
                            if(i.Children){
                               recurFunc(i.Children,i);
                            }
                        })
                    }
                    recurFunc(this.trees,this.trees);
                },
                open(m){
                	//
                	m.isExpand = !m.isExpand;
           
                	if(typeof this.expandfunc == "function" && m.isExpand) {
                		if(m.loadNode!=2) {
		                	//
		                    this.expandfunc.call(null,m);
		                }else {
		                	m.isFolder = !m.isFolder;
		                }
	                } else {
                        m.isFolder = !m.isFolder;
	                }
                }
        	},
        	computed:{
        		// 给（根 和 子树）赋值不同的样式
                rootClass(){
                	 var strRootClass = '';
                     
                     // 根判断
                	 if(this.root=='0'){
                       this.model.Children = this.model.Children || [];
                       strRootClass =  (this.num==0 && this.model.Children.length==0) ? "roots_docu" : (this.nodes==1) || (this.num==0 && this.nodes!=this.num+1) ? 
                         "root_" : (this.nodes == this.num+1) ? "bottom_" : "center_";
                     
                     // 子树判断
                	 }else if(this.root=='1') {
                        this.model.Children = this.model.Children || [];
                        strRootClass =  this.nodes>1 && this.model.Children.length>0 && this.nodes!=this.num+1
                         ? "center_" : 
                            (this.num == 0 && this.nodes>1) || (this.nodes!=this.num+1) ? "center_docu" : 
                                 this.nodes == 1&&this.num!=0 || (this.nodes==this.num+1 && this.model.Children.length>0)   ? "bottom_" : "bottom_docu";
                	 }
                	 return  strRootClass
                },
                // 是否有儿子节点
                isChildren(){
                     return this.num+1 != this.nodes;
                },
                // 展开/收起
                prefixClass(){
                	var returnChar = "";
                	if(this.rootClass.indexOf("docu")==-1){
	                	if(this.model.isFolder){
                           returnChar = "open";
	                	}else {
                           returnChar = 'close'
	                	}
						// 
	                }
	                if(this.model.Children.length==0 && this.rootClass.indexOf("docu")==-1){
                        returnChar = 'docu'
	                }
	                
	                return returnChar;
                },
                liClassVal(){
                	 return "level"+this.num;
                },
                spanClassVal(){
                	 return "button level"+this.num+" switch "+this.rootClass+this.prefixClass;
                },
                aClassVal(){
                     return this.model.clickNode ? "level"+this.num+' curSelectedNode':"level"+this.num;
                },
                ulClassVal(){
                	return this.ischildren && this.model.Children.length>0 ?"level"+this.num+' line':"level"+this.num;
                },
				clb(){
					return this.rootClass=="bottom_"? 'l-b l-b-d':'l-b'
				},
				ctb(){
					return "t-b "
				}
        	},
            template: 
            `<li :class="liClassVal">
				<div :class="clb" v-if="rootClass!='root_'"></div>
				<div :class="ctb" v-if="rootClass!='root_'"></div>
				<span :class="spanClassVal" @click='open(model)'></span>
				<a :class="aClassVal" @click='Func(model)' @contextmenu.prevent='cxtmenufunc(model)'>
				    <span :class="{loadSyncNode:model.loadNode==1}" v-if='model.loadNode==1'></span>
				    <span :class='model.iconClass' v-show='model.iconClass' v-else></span>
					<span class="node_name">{{model.User.user_name}}<span style="color:rgb(45, 140, 240);">({{model.User.group_name}})</span></span>
				</a>
				<ul :class="ulClassVal" v-show='model.isFolder'>
					<ztree-item v-for="(item,i) in model.Children" :key='i' :callback='callback' :expandfunc='expandfunc' :cxtmenufunc='cxtmenufunc' :model.sync="item" :num.sync='i' root='1' :nodes.sync='model.Children.length' :trees.sync='trees'></ztree-item>
				</ul>
			</li>`
		}
	},
	update(){
		this.initTreeData();
	},
	mounted(){
		
		Vue.nextTick(()=>{
			this.initTreeData();
		})
	}
}
</script>